package com.kersci.heartratereader.utils

import android.content.Context
import com.clj.fastble.data.BleDevice
import com.kersci.heartratereader.BleDeviceService
import com.kersci.heartratereader.R
import com.safframework.log.L

class DeviceManager {
    companion object {
        const val EVENT_DEVICE_ADDED = 0
        const val EVENT_DEVICES_CLEAR = 1
        const val EVENT_SCAN_STARTED = 2
        const val EVENT_SCAN_FINISHED = 3
        const val EVENT_SCANNING = 4
        const val EVENT_MAX_DEVICE_ID = 1000

        fun getEventMessage(context: Context, event: Int) : String {
            when(event) {
                EVENT_SCANNING -> return context.getString(R.string.scanning)
                EVENT_DEVICE_ADDED -> return context.getString(R.string.device_added)
                EVENT_DEVICES_CLEAR -> return context.getString(R.string.device_clear)
                EVENT_SCAN_FINISHED -> return context.getString(R.string.scan_finished)
                EVENT_SCAN_STARTED -> return context.getString(R.string.scan_starting)
            }
            return "Unknown event"
        }
    }

    interface DeviceChangeListener {
        fun onDeviceChanged(event: Int)
    }

    interface ScanEventListener {
        fun onScanEventChanged(event: Int)
    }

    private val deviceChangeListeners = arrayListOf<DeviceChangeListener>()

    private val devices = arrayListOf<HeartRateDevice>()

    @Synchronized
    fun registerDeviceListener(changeListener: DeviceChangeListener) {
        if (deviceChangeListeners.contains(changeListener)) {
            val index = deviceChangeListeners.indexOf(changeListener)
            deviceChangeListeners[index] = changeListener
        } else {
            deviceChangeListeners.add(changeListener)
        }
    }

    @Synchronized
    fun unregisterDeviceListener(changeListener: DeviceChangeListener) {
        val index = deviceChangeListeners.indexOf(changeListener)
        if (index >= 0) {
            deviceChangeListeners.remove(changeListener)
        }
    }

    private fun notifyChangedLocked(event: Int) {
        for (listener in deviceChangeListeners) {
            listener.onDeviceChanged(event)
        }
    }

    private val scanChangeListeners = arrayListOf<ScanEventListener>()

    @Synchronized
    fun registerScanEventListener(listener: ScanEventListener) {
        if (scanChangeListeners.contains(listener)) {
            val index = scanChangeListeners.indexOf(listener)
            scanChangeListeners[index] = listener
        } else {
            scanChangeListeners.add(listener)
        }
    }

    @Synchronized
    fun unregisterScanEventListener(listener: ScanEventListener) {
        val index = scanChangeListeners.indexOf(listener)
        if (index >= 0) {
            scanChangeListeners.remove(listener)
        }
    }

    fun notifyBleScanEventChanged(event: Int) {
        for (listener in scanChangeListeners) {
            listener.onScanEventChanged(event)
        }
    }

    @Synchronized
    fun getDeviceCount(): Int {
        return devices.size
    }
    private fun isSameDevice(device: HeartRateDevice, name:String, mac: String): Boolean {
        return device.name.equals(name) && device.mac.equals(mac)
    }

    @Synchronized
    fun addDevice(name:String, mac: String, rssi: Int, bleDevice: BleDevice) {
        L.d("add device $name, $mac")
        for (device in devices) {
            if (isSameDevice(device, name, mac)) {
                return
            }
        }

        devices.add(HeartRateDevice(name, mac, rssi, bleDevice))
        notifyChangedLocked(EVENT_DEVICE_ADDED)
    }

    @Synchronized
    fun clear() {
        devices.clear()
        notifyChangedLocked(EVENT_DEVICES_CLEAR)
    }

    @Synchronized
    fun getDevices(): List<HeartRateDevice> {
        return devices
    }

    @Synchronized
    fun getDevice(index: Int): HeartRateDevice? {
        return if (index >= 0 && index < devices.size) {
            devices[index]
        } else {
            null
        }
    }
}